﻿using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Text.RegularExpressions;
using System.Collections.Generic; 
using umbraco.cms.businesslogic.media;
using Commerce.Promotions;
using Commerce.Common;
using CommerceForUmbraco.usercontrols.usercontrols.commerce;


namespace CommerceForUmbraco.usercontrols
{
    public partial class CategoryProductsList : System.Web.UI.UserControl
    {
        #region Properties

        private string _PropCategoryId;

        public string PropCategoryId
        {
            get { return _PropCategoryId; }
            set { _PropCategoryId = value; }
        }

        #endregion

        #region ProWorks Paging Control Helper Properties and Fields

        private int RowCount
        {
            get
            {
                if (ViewState["RowCount"] == null)
                {
                    ViewState["RowCount"] = 0;
                }

                return Convert.ToInt32(ViewState["RowCount"]);
            }
            set
            {
                ViewState["RowCount"] = value;
            }
        }
        private int PageSize
        {
            get
            {
                if (ViewState["PageSize"] == null)
                {
                    ViewState["PageSize"] = this.DefaultPageSize;
                }

                return Convert.ToInt32(ViewState["PageSize"]);
            }
            set
            {
                ViewState["PageSize"] = value <= 0 ? this.RowCount : value;
            }
        }
        private int CurrentPageIndex
        {
            get
            {
                if (ViewState["CurrentPageIndex"] == null)
                {
                    ViewState["CurrentPageIndex"] = this.DefaultPageIndex;
                }

                return Convert.ToInt32(ViewState["CurrentPageIndex"]);
            }
            set
            {
                ViewState["CurrentPageIndex"] = value <= 0 ? 0 : value;
            }
        }
        private string SortOrderDetails
        {
            get
            {
                if (ViewState["SortOrderDetails"] == null)
                {
                    ViewState["SortOrderDetails"] = this.DefaultSortOrderDetails;
                }

                return Convert.ToString(ViewState["SortOrderDetails"]);
            }
            set
            {
                ViewState["SortOrderDetails"] = value != null ? value : "";
            }
        }

        #endregion

        #region Umbraco Configuration Properties

        public string BarDelimitedPageSizes
        {
            get;
            set;
        }

        public string BarDelimitedSortOrderDisplayItems
        {
            get;
            set;
        }

        public string BarDelimitedSortOrderClauseItems
        {
            get;
            set;
        }

        public string DefaultSortOrderDetails
        {
            get;
            set;
        }

        public int DefaultPageSize
        {
            get;
            set;
        }

        public int DefaultPageIndex
        {
            get;
            set;
        }

        public int DefaultImage
        {
            get;
            set;
        }

        #endregion

        /// <summary>
        /// To implement one or more ProWorks paging controls
        /// with a repeater, wire them up in the Page_Init method...
        /// </summary>
        protected void Page_Init(object sender, EventArgs e)
        {
            this.PWPagingControl1.OnPagedControlChanged += new PWPagingControl.PagedControlChanged(OnPagedControlChanged);
            this.PWPagingControl2.OnPagedControlChanged += new PWPagingControl.PagedControlChanged(OnPagedControlChanged);
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (this.IsPostBack == false)
            {
                // First time page/control loaded...
                InitUserDefinedUmbracoProperties();
                FetchData();
                InitPageControls();
                UpdatePagingControls();
            }
            else
            {
                // Page and control(s) being posted back....
                FetchData();
                UpdatePagingControls();
            }
        }

        #region ProWorks Paging Control Methods and Handlers
        private void InitUserDefinedUmbracoProperties()
        {
            if (string.IsNullOrEmpty(BarDelimitedPageSizes))
            {
                BarDelimitedPageSizes = "10|20|30|40|50";
            }

            if (string.IsNullOrEmpty(BarDelimitedSortOrderDisplayItems))
            {
                BarDelimitedSortOrderDisplayItems = "Products A-Z|Products Z-A";
            }

            if (string.IsNullOrEmpty(BarDelimitedSortOrderClauseItems))
            {
                BarDelimitedSortOrderClauseItems = "ProductName~ASC|ProductName~DESC";
            }

            if (string.IsNullOrEmpty(DefaultSortOrderDetails))
            {
                DefaultSortOrderDetails = "ProductName~ASC";
            }

            if (DefaultPageSize == 0) // zero not allowed - would cause divide-by-zero error!
            {
                int[] pageSizes = this.GetIntArray(BarDelimitedPageSizes);
                if (pageSizes != null && pageSizes.Length > 0)
                {
                    DefaultPageSize = pageSizes[0]; // default to first page size
                }
            }

            // NOTE:  don't need to init DefaultPageIndex since 0 is fine
        }

        protected void InitPageControls()
        {

            int[] pageRanges = GetIntArray(this.BarDelimitedPageSizes);
            this.PageSize = this.DefaultPageSize;
            this.CurrentPageIndex = this.DefaultPageIndex;
            this.SortOrderDetails = this.DefaultSortOrderDetails;

            this.PWPagingControl1.InitPageSizeList(pageRanges, this.PageSize, this.RowCount, true);
            this.PWPagingControl2.InitPageSizeList(pageRanges, this.PageSize, this.RowCount, true);

            // Initialize the sorting aspects of the display
            string[] sortOrderDisplayNames = GetStringArray(this.BarDelimitedSortOrderDisplayItems);
            string[] sortOrderClauses = GetStringArray(this.BarDelimitedSortOrderClauseItems);

            this.PWPagingControl1.InitSortOrderList(sortOrderDisplayNames, sortOrderClauses, PWPagingControl.SortOrderClause.FromString(this.SortOrderDetails));
            this.PWPagingControl2.InitSortOrderList(sortOrderDisplayNames, sortOrderClauses, PWPagingControl.SortOrderClause.FromString(this.SortOrderDetails));
        }

        protected int[] GetIntArray(string barDelimitedNumbers)
        {
            if (string.IsNullOrEmpty(barDelimitedNumbers))
            {
                return null;
            }

            char[] delimiter = { '|' };

            string[] items = barDelimitedNumbers.Split(delimiter, StringSplitOptions.RemoveEmptyEntries);

            if (items == null || items.Length == 0)
            {
                return null;
            }

            List<int> list = new List<int>();
            int iResult;
            foreach (string item in items)
            {
                if (int.TryParse(item, out iResult))
                {
                    list.Add(iResult);
                }
            }

            if (list.Count > 0)
            {
                return list.ToArray();
            }

            return null;
        }

        protected string[] GetStringArray(string barDelimitedStrings)
        {
            if (string.IsNullOrEmpty(barDelimitedStrings))
            {
                return null;
            }

            char[] delimeter = { '|' };

            string[] items = barDelimitedStrings.Split(delimeter, StringSplitOptions.RemoveEmptyEntries);

            if (items == null || items.Length == 0)
            {
                return null;
            }

            return items;
        }


        protected void UpdatePagingControls()
        {
            this.PWPagingControl1.CreatePagingControl(this.PageSize, this.RowCount, this.CurrentPageIndex);
            this.PWPagingControl2.CreatePagingControl(this.PageSize, this.RowCount, this.CurrentPageIndex);
        }

        protected void SyncPageSizes(PWPagingControl pagingContol)
        {
            if (pagingContol == PWPagingControl1)
            {
                PWPagingControl2.UpdatePageSizeInList(PWPagingControl1.PageSize);
            }
            else
            {
                PWPagingControl1.UpdatePageSizeInList(PWPagingControl2.PageSize);
            }
        }

        protected void SyncSortOrderDisplay(PWPagingControl pagingContol)
        {
            if (pagingContol == PWPagingControl1)
            {
                PWPagingControl2.UpdateSortOrderInList(PWPagingControl1.SortOrderDetails);
            }
            else
            {
                PWPagingControl1.UpdateSortOrderInList(PWPagingControl2.SortOrderDetails);
            }
        }

        protected void OnPagedControlChanged(object sender, PWPagingControl.ProWorksPagingControlEventArgs args)
        {
            this.CurrentPageIndex = args.CurrentPageIndex;
            this.PageSize = args.PageSize;
            this.SortOrderDetails = args.SortOrderClause != null ? args.SortOrderClause.ToString() : "";

            if (args.EventType == PWPagingControl.ProWorksPagingControlEventType.CurrentPageOnly)
            {
                // All we need to do is sync up...
                return;
            }

            if (args.EventType == PWPagingControl.ProWorksPagingControlEventType.PageSizeOnly)
            {
                PWPagingControl pagingControl = sender as PWPagingControl;
                SyncPageSizes(pagingControl);
            }

            if (args.EventType == PWPagingControl.ProWorksPagingControlEventType.SortOrderOnly)
            {
                PWPagingControl pagingControl = sender as PWPagingControl;
                SyncSortOrderDisplay(pagingControl);
            }

            FetchData();
            UpdatePagingControls();
        }

        #endregion

        protected void FetchData()
        {
            try
            {
                int catID;
                if (!Int32.TryParse(PropCategoryId, out catID))
                {
                    catID = 0;
                }

                string categoryName = Commerce.Common.Utility.UnwindRewriteParam(PropCategoryId);

                Category currentCategory = null;

                CategoryCollection categories = new CategoryCollection().Load();
                foreach (Category category in categories)
                {
                    if (category.CategoryID == catID || category.UrlFriendly.ToLower().Equals(PropCategoryId.ToLower())) // || category.CategoryName.ToLower().Equals(categoryName.ToLower()))
                    {
                        currentCategory = category;

                        break;
                    }
                }

                //make sure we have a product
                TestCondition.IsTrue(currentCategory.IsLoaded, "Invalid url/category id");

                Commerce.Common.ProductCollection catProductsTemp = currentCategory.GetProductCollection();

                Commerce.Common.ProductCollection catProducts = new Commerce.Common.ProductCollection();

                foreach (var prod in catProductsTemp)
                {
                    if (prod.Status != ProductStatus.Inactive)
                    {
                        catProducts.Add(prod);
                    }
                }

                PWPagingControl.SortOrderClause sortOrderClause = PWPagingControl.SortOrderClause.FromString(this.SortOrderDetails);

                if (sortOrderClause != null)
                {
                    catProducts.Sort(sortOrderClause.SortColumnName, sortOrderClause.Ascending);
                }

                // NOTE: by binding to a PagedDataSource, the ProWorks page control(s)
                // can sync to the repeater and provide a paging UI...
                PagedDataSource pagedDataSource = new PagedDataSource();
                pagedDataSource.AllowPaging = true;

                DataTable dt = catProducts.ToDataTable();
               
                // Example expected format: State, ZipCode DESC
                /////dt.DefaultView.Sort = this.SortOrderClause;

                // SPECIAL CASE: update the dt's defaultImage value (an ID) 
                // with the actual media url...
                foreach (DataRow dr in dt.Rows)
                {
                    int mediaId = 0;
                    if( int.TryParse(dr["defaultImage"].ToString(), out mediaId) )
                    {
                        if (mediaId > 0)
                        {
                            if (Media.IsNode(mediaId))
                            {
		                        Media temp = new Media(mediaId);
                                if (temp != null)
								{							
			                        if (temp.getProperty("crops").Value.ToString().Trim().Length > 0)
			                        {
			                            string imagecrops = temp.getProperty("crops").Value.ToString();

			                            // Regex to pull out crop out of xml
			                            string pattern = @"<crop name=""Large Thumbnail"".+url=""(?'url'.*_Large Thumbnail\.jpg?)"" />";
			                            MatchCollection matches = Regex.Matches(imagecrops, pattern);

			                            string imageloc = "";

			                            foreach (Match match in matches)
			                            {
			                                if (match.Groups["url"].Success == true)
			                                {
			                                    imageloc = match.Groups["url"].Value;
			                                }
			                            }

			                            dr["defaultImage"] = Server.UrlEncode(imageloc);
			                        }
			                        else if (temp.getProperty("umbracoFile").Value.ToString().Trim().Length > 0)
			                        {
			                            dr["defaultImage"] = Server.UrlEncode(temp.getProperty("umbracoFile").Value.ToString());
			                        }
			                        else
			                        {
				                        if (DefaultImage > 0)
				                        {
				                            if (Media.IsNode(DefaultImage))
				                            {
					                            Media tempDefault = new Media(DefaultImage);
				                                if (tempDefault != null)
				                                {
						                            dr["defaultImage"] = Server.UrlEncode(tempDefault.getProperty("umbracoFile").Value.ToString());
												}
											}
										}
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        if (DefaultImage > 0)
                        {
                            if (Media.IsNode(DefaultImage))
                            {
                                Media temp = new Media(DefaultImage);
                                if (temp != null)
                                {
                                    dr["defaultImage"] = Server.UrlEncode(temp.getProperty("umbracoFile").Value.ToString());
                                }
                            }
                        }
                    }
                }

                pagedDataSource.DataSource = dt.DefaultView;
                this.RowCount = dt.Rows.Count;

                pagedDataSource.CurrentPageIndex = this.CurrentPageIndex;
                pagedDataSource.PageSize = this.PageSize;

                CategoryProductsRepeater.DataSource = pagedDataSource;
                CategoryProductsRepeater.DataBind();
            }
            catch(System.Exception ex)
            {
                string m = ex.Message;
                // TODO: failed to bind...no records???
            }
        }
    }
}